package com.tpix;

import  java.util.*;
import javax.servlet.http.HttpServletRequest;
import com.google.appengine.api.blobstore.*;
import com.google.appengine.api.images.*;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.tpix.photo.Photo;
import com.tpix.photo.PhotoDAO;

public class PixieCore implements java.io.Serializable {

	// private data members
	private static final long serialVersionUID = 8153516841221133109L;
	private String album;
	private Key key;
	
	// constructors
	public PixieCore() {
		this.album = "Default";
		this.key = null;
	}
	
	// public interface
	public String getUserName() {
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		String name;
		if (user != null) {
			name = user.getNickname();
		} else {
			name = "Default User";
		}
		return name;
	}
	public String getLogoutURL(HttpServletRequest request) {
		UserService userService = UserServiceFactory.getUserService();
		String thisURL = request.getRequestURI();
		return userService.createLogoutURL(thisURL);
	}
	/*
	 * Returns true if the user is logged in as a google user
	 */
	public boolean loggedIn() {
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		if (user != null)
			return true;
		else
			return false;
	}
	public String getAlbum() {
		return this.album;
	}
	public void setAlbum(String newAlbum) {
		this.album = newAlbum;
	}
	/*
	 * Given a photo 
	 */
	/*
	 * Returns a List of URLs for all of this user's photos in the 
	 * currently selected album.
 	 * Depends on PhotoDAO to interact with datastore and blobstore.
	 */
	public List<String> getAlbumURLs() { 
		PhotoDAO dao = new PhotoDAO();
		List<String> sameAlbumUrls = dao.getByAlbumName(this.album, this.getUserName());
		return sameAlbumUrls;
	}	
	/*
	 * Returns List of URLs for all of this user's photos in the given album
	 * and sets the given album as the currentl selected album.
	 * Depends on PhotoDAO to interact with datastore and blobstore.
	 */
	public List<String> getAlbumURLs(String album) {
		// updates album, then gets URLS
		this.setAlbum(album);
		return this.getAlbumURLs();
	}
	/*
	 * Returns List of URLs for all of this user's photos with the given tag.
	 * Depends on PhotoDAO to interact with datastore and blobstore.
	 */
	public List<String> getTagURLs(String tag) { 
		PhotoDAO dao = new PhotoDAO();
		List<String> sameTagUrls = dao.getByTagName(tag, this.getUserName());
		return sameTagUrls;
	}	
	/*
	 * Returns ArrayList of all unique album names for this user's photos
	 */
	public ArrayList<String> getAlbums() {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Query q = new Query("Photo");
		q.addFilter("user", Query.FilterOperator.EQUAL, this.getUserName());
		PreparedQuery pq = datastore.prepare(q);
		ArrayList<String> albumList = new ArrayList<String>();
		for (Entity result : pq.asIterable()) {
			String album = (String) result.getProperty("albumName");
			if (!albumList.contains(album)) {
				albumList.add(album);
			}
		}
		return albumList;
	}
	
	/*
	 *  Return ArrayList of all unique tags from all of this user's photos
	 */
	public ArrayList<String> getTags() {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Query q = new Query("Photo");
		q.addFilter("user", Query.FilterOperator.EQUAL, this.getUserName());
		PreparedQuery pq = datastore.prepare(q);
		// tagList is the list of unique tags that will be returned
		ArrayList<String> tagList = new ArrayList<String>();
		// iterate over all photos for this user, finding tags
		for (Entity result : pq.asIterable()) {
			// get tags from this photo
			ArrayList<String> tags = (ArrayList<String>) result.getProperty("tagList"); 
			if (tags != null){
				// iterate through this entity's tags, add if they haven't already been added.
				Iterator<String> itr = tags.iterator();
				while(itr.hasNext()) {
					String tag = (String)itr.next();
					// remove leading and trailing spaces
					tag = tag.trim();
					// add tag to tagList if it isn't already there
					if (!tagList.contains(tag)) {
						tagList.add(tag);
					}
				}
			} 		
		}
		return tagList;
	}
	
	/* ****************************************************
	 * Returns ArrayList of Keys for this user's photos in the given album
	 */
	public ArrayList<Key> getAlbumKeys() {
		return getAlbumKeys(this.album);
	}
	public ArrayList<Key> getAlbumKeys(String album) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Query q = new Query("Photo");
		q.addFilter("user", Query.FilterOperator.EQUAL, this.getUserName());
		q.addFilter("albumName", Query.FilterOperator.EQUAL, album);

		PreparedQuery pq = datastore.prepare(q);
		ArrayList<Key> keyList = new ArrayList<Key>();
		for (Entity result : pq.asIterable()) {
			Key key = result.getKey();
			keyList.add(key);
		}
		return keyList;
	}
	public List<Key> getTagKeys(String tag) { 
		PhotoDAO dao = new PhotoDAO();
		List<Key> sameTagKeys = dao.getKeysByTagName(tag, this.getUserName());
		return sameTagKeys;
	}	

	public String BlobkeyFromKey(Key key) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Entity entity;
		try {
			entity = datastore.get(key);
		} catch (EntityNotFoundException e) {
			return null;
		}
		String blobkey = (String)entity.getProperty("blobKey");
		return blobkey;
	}
	public String URLfromKey(Key key) {
		ImagesService imageService = ImagesServiceFactory.getImagesService();
		BlobKey blobkey = new BlobKey(BlobkeyFromKey(key));
		String URL = imageService.getServingUrl(blobkey);
		return URL;
	}
	public void setKey(Key key) {
		this.key = key;
	}
	public Key getKey() {
		return this.key;
	}
	public Photo photoFromKey(Key key) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Entity entity;
		try {
			entity = datastore.get(key);
		} catch (EntityNotFoundException e) {
			return null;
		}

		String title = (String)entity.getProperty("title");
		String caption = (String)entity.getProperty("caption");
		String blobkey = (String)entity.getProperty("blobKey");
		String albumName = (String)entity.getProperty("albumName");
		//String date = (String)entity.getProperty("date");
		String description = (String)entity.getProperty("description");
		String user = (String)entity.getProperty("user");
		List<String> taglist = (List<String>)entity.getProperty("tagList");
		Photo photo = new Photo(title, caption, blobkey);
		photo.setAlbumName(albumName);
		//photo.setDate(date);
		photo.setDescription(description);
		photo.setUser(user);
		
		return photo;

	}
	public void deletePhoto(Key key) {
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		datastore.delete(key);
	}
	/* *************************************************** */

	
}
